﻿/// Name - MyHealth/HealthQuestionairePrint.cs
/// Description - Displays the Questionaire all on one page, intended for printing.
/// Programmer - Dan Yatzeck
/// Date coded - 11/30/2011
/// Arguments - None
/// Variables -
///     _presenter - Object linking to parent Presenter
///     showAnswers - Flag indicating whether user answers should be displayed
/// Files accessed by this code artifact - None
/// Files changed by this code artifact - None
/// I/O -
///     Input - Questionaire questions, including answers
///     Output - Printable Web page
/// Error Handling - None
/// Modifications -
///     1.0 - Initial coding
/// Known Faults -
///     1.0 - Toggling show answers requires some workaround code that is inefficient; Textboxes may not show all data,
///         instead we should not use textboxes and use literals to avoid this limitation but ran out of time to
///         implement

using System;
using Microsoft.Practices.ObjectBuilder;
using System.Collections.Generic;
using Common;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace CSC440TeamOne.MyHealth.Views
{
    /// <summary>
    /// Printable Questionaire
    /// </summary>
	public partial class HealthQuestionairePrint : Microsoft.Practices.CompositeWeb.Web.UI.Page, IHealthQuestionairePrintView
	{
        
		private HealthQuestionairePrintPresenter _presenter;
        private bool showAnswers;

        /// <summary>
        /// Page Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		protected void Page_Load(object sender, EventArgs e)
		{
			if (!this.IsPostBack)
			{
				this._presenter.OnViewInitialized();

                this.showAnswers = true;
			}
            this._presenter.OnViewLoaded();

            if (this.IsPostBack)
            {
                // Check if show answers flag is turned off
                if (Request.Form[hiddenShowAnswers.UniqueID] == "Yes")
                {
                    this.showAnswers = false;
                }
                else if (Request.Form[hiddenShowAnswers.UniqueID] == "No")
                {
                    // Another ViewState workaround, allowing showAnswers to be defaulted
                    // to TRUE on !postback rather than trying to deal with it during postback
                    // (checkboxes wouldn't trigger properly after postback)
                    Response.Redirect(Request.RawUrl);  
                    this.showAnswers = true;
                }
            }

            // Modify "Show Answers" toggle button and hidden control value based on what is selected
            toggleShowAnswers();

            // Get questions from presenter
            List<Question> questions = _presenter.getAllQuestions();

            // Add controls to the screen for printing
            ConstructPageElements(questions);
			
		}


        /// <summary>
        /// When this object is instantiated, create the presenter link
        /// </summary>
		[CreateNew]
		public HealthQuestionairePrintPresenter Presenter
		{
			get
			{
				return this._presenter;
			}
			set
			{
				if(value == null)
					throw new ArgumentNullException("value");

				this._presenter = value;
				this._presenter.View = this;
			}
		}

        /// <summary>
        /// Adds question controls to the page
        /// </summary>
        private void ConstructPageElements(List<Question> questions)
        {
            // Counter for question numbers
            int questionNumber = 0;

            // Loop through questions
            foreach (Question question in questions)
            {
                if (question.ShowOnPrintout)
                {
                    // Increment question number
                    questionNumber++;

                    // Add question number and text
                    Label label = new Label();
                    label.Text = questionNumber.ToString() + ". " + question.QuestionText;
                    pnlQuestions.Controls.Add(label);

                    pnlQuestions.Controls.Add(new LiteralControl("<br />"));

                    // Create answer controls based on answer type in Question object
                    switch (question.AnswerControlType)
                    {
                        case Question.Types.RadioButton:

                            RadioButtonList answercontrolRADIO = new RadioButtonList();
                            answercontrolRADIO.ID = "Question" + question.QuestionID.ToString();
                            
                            // Radio button assumes answer controls are contained in ChildItems
                            foreach (Question item in question.ChildItems)
                            {
                                ListItem listitem = new ListItem();
                                listitem.Value = item.QuestionText;

                                // Check if printing answers and select if this is the answer
                                if (this.showAnswers)
                                {
                                    if (question.AnswerText == item.QuestionText)
                                    {
                                        listitem.Selected = true;
                                    }
                                }

                                answercontrolRADIO.Items.Add(listitem);
                            }

                            // Add answer controls
                            pnlQuestions.Controls.Add(answercontrolRADIO);
                        
                            break;

                        case Question.Types.TextBox:

                            TextBox answercontrolTEXT = new TextBox();
                            answercontrolTEXT.ID = "Question" + question.QuestionID.ToString();

                            // Check if printing answers and select if this is the answer
                            if (this.showAnswers)
                            {

                                answercontrolTEXT.Text = question.AnswerText;
                            }
                            
                            // Add answer controls
                            pnlQuestions.Controls.Add(answercontrolTEXT);
                        
                            break;

                        case Question.Types.CheckBox:

                            CheckBoxList answercontrolCHECK = new CheckBoxList();
                            answercontrolCHECK.ID = "Question" + question.QuestionID.ToString();

                            // Checkbox assumes answer controls are contained in ChildItems
                            foreach (Question item in question.ChildItems)
                            {
                                ListItem listitem = new ListItem();
                                listitem.Value = item.QuestionText;

                                // Check if printing answers and select if this is the answer
                                if (this.showAnswers)
                                {
                                    if (item.Answered)
                                    {
                                        listitem.Selected = true;
                                    }
                                }

                                answercontrolCHECK.Items.Add(listitem);
                            }

                            // Add answer controls
                            pnlQuestions.Controls.Add(answercontrolCHECK);
                        
                            break;

                        case Question.Types.Literal:

                            // Do nothing, not needed for the printout
                            break;
                    } // switch question.type
                    
                    // Carriage return after control
                    pnlQuestions.Controls.Add(new LiteralControl("<br />"));

                    // Space between questions
                    pnlQuestions.Controls.Add(new LiteralControl("<br />"));

                } // if showonprintout

            } // foreach question
        }

        /// <summary>
        /// Change show answers toggle button to show appropriate message
        /// </summary>
        private void toggleShowAnswers()
        {
            if (this.showAnswers)
            {
                btnShowAnswersToggle.Text = "Hide Answers";
                hiddenShowAnswers.Value = "Yes";
            }
            else
            {
                btnShowAnswersToggle.Text = "Show Answers";
                hiddenShowAnswers.Value = "No";
            }
        }

        /// <summary>
        /// Override render function to remove answers if needed.  Based on the page lifecycle of ASP.NET, the
        /// page_load happens, which creates the controls, then the control code is executed, then the 
        /// page is rendered.  When the control code is executed, the viewstate is applied to all the controls.  To get around
        /// this, the controls are blanked out during rendering.
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            // If answers are turned off, go through the page controls and remove the answers.  I couldn't get
            // turning off ViewState to work with dynamic controls so this is my workaround.
            if (!this.showAnswers)
            {
                foreach (Control ctrl in pnlQuestions.Controls)
                {
                    if (ctrl is TextBox)
                    {
                        ((TextBox)ctrl).Text = "";
                    }
                    else if (ctrl is RadioButtonList)
                    {
                        ((RadioButtonList)ctrl).SelectedIndex = -1;
                    }
                    else if (ctrl is CheckBoxList)
                    {
                        foreach (ListItem item in ((CheckBoxList)ctrl).Items)
                        {
                            item.Selected = false;
                        }
                    }
                }
            }

            base.Render(writer);
        }
	}
}

